package audit

import (
	"counter-help/admin/server/global"
	"counter-help/admin/server/model/audit"
	auditReq "counter-help/admin/server/model/audit/request"
	"counter-help/admin/server/model/common/response"
	"counter-help/admin/server/utils"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"io"
	"os"
)

type TechnicalVerificationApi struct{}

// CreateOrUpdateTechnicalVerification 创建技术审核
func (api *TechnicalVerificationApi) CreateOrUpdateTechnicalVerification(c *gin.Context) {
	// 获取上传的认证照片文件（允许文件未上传）
	certificateImageFile, certificateImageHeader, err := c.Request.FormFile("certificateImage")
	var imagePath string // 初始化路径变量，未上传文件时保持为空
	if err != nil {
		// 未上传文件或文件获取失败，继续处理其他数据
		certificateImageFile = nil
		fmt.Println("认证照片未上传或获取失败:", err)
	} else {
		defer certificateImageFile.Close() // 确保文件在函数结束后被关闭
	}

	// 绑定请求中的 JSON 数据到结构体
	var req auditReq.TechnicalVerification
	if err := c.ShouldBind(&req); err != nil {
		response.FailWithMessage("数据绑定失败", c)
		return
	}

	userID := utils.GetUserID(c)
	imageDir := fmt.Sprintf("uploads/technical_verifications/%d", userID)

	// 仅当上传了文件时，定义存储路径和保存文件
	if certificateImageFile != nil && certificateImageHeader != nil {
		imagePath = fmt.Sprintf("%s/%s", imageDir, certificateImageHeader.Filename)

		// 检查并创建目录
		if err := os.MkdirAll(imageDir, os.ModePerm); err != nil {
			global.GVA_LOG.Error("创建存储目录失败!", zap.Error(err))
			response.FailWithMessage("创建存储目录失败", c)
			return
		}

		// 清空目录中的所有文件
		files, err := os.ReadDir(imageDir)
		if err != nil {
			global.GVA_LOG.Error("读取存储目录失败!", zap.Error(err))
			response.FailWithMessage("读取存储目录失败", c)
			return
		}
		for _, file := range files {
			if err := os.Remove(fmt.Sprintf("%s/%s", imageDir, file.Name())); err != nil {
				global.GVA_LOG.Error("删除旧文件失败", zap.Error(err))
				response.FailWithMessage("删除旧文件失败", c)
				return
			}
		}

		// 手动保存文件数据到服务器
		out, err := os.Create(imagePath)
		if err != nil {
			global.GVA_LOG.Error("认证照片保存失败", zap.Error(err))
			response.FailWithMessage("认证照片保存失败", c)
			return
		}
		defer out.Close()

		// 将文件内容从 certificateImageFile 拷贝到目标文件
		if _, err := io.Copy(out, certificateImageFile); err != nil {
			global.GVA_LOG.Error("文件写入失败", zap.Error(err))
			response.FailWithMessage("文件写入失败", c)
			return
		}
	}

	// 构建技术审核记录
	technicalVerification := audit.TechnicalVerification{
		UserID:              userID,
		CompanyName:         req.CompanyName,
		WorkDuration:        req.WorkDuration,
		StatisticalTools:    req.StatisticalTools,
		BusinessDescription: req.BusinessDescription,
		CertificateImage:    imagePath, // 未上传文件时路径为空
		IsReviewed:          false,
	}

	// 创建或更新技术审核记录
	if err := auditTechnicalService.CreateOrUpdateTechnicalVerification(technicalVerification); err != nil {
		global.GVA_LOG.Error("创建或更新技术审核失败", zap.Error(err))
		response.FailWithMessage("创建或更新技术审核失败", c)
		return
	}

	response.OkWithMessage("创建或更新技术审核成功", c)
}

// GetTechnicalVerification 获取技术审核信息
func (api *TechnicalVerificationApi) GetTechnicalVerification(c *gin.Context) {
	userID := utils.GetUserID(c)
	verification, err := auditTechnicalService.GetTechnicalVerification(userID)
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		global.GVA_LOG.Error("获取技术审核失败", zap.Error(err))
		response.CommonFailWithMessage("获取技术审核失败", c)
		return
	}
	response.OkWithDetailed(verification, "获取技术审核成功", c)
}

// ApproveTechnicalVerification 审核通过
func (api *TechnicalVerificationApi) ApproveTechnicalVerification(c *gin.Context) {
	var request struct {
		UserID uint `json:"userId" form:"userId" binding:"required"`
	}
	if err := c.ShouldBindJSON(&request); err != nil {
		response.FailWithMessage("数据绑定失败", c)
		return
	}
	if err := auditTechnicalService.ApproveTechnicalVerification(request.UserID); err != nil {
		global.GVA_LOG.Error("技术审核通过失败", zap.Error(err))
		response.FailWithMessage("技术审核通过失败", c)
		return
	}
	response.OkWithMessage("技术审核通过", c)
}

// RejectTechnicalVerification 审核不通过
func (api *TechnicalVerificationApi) RejectTechnicalVerification(c *gin.Context) {
	userID := utils.GetUserID(c)
	var req struct {
		RejectionReason string `json:"rejectionReason"`
		UserID          uint   `json:"userId" form:"userIdd,omitempty" form:"userId,omitempty" `
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage("数据绑定失败", c)
		return
	}

	source := utils.GetUserSource(c)
	if userID == 0 || source == "system" {
		userID = req.UserID
	}
	if userID == 0 {
		response.FailWithMessage("参数异常", c)
		return
	}
	if err := auditTechnicalService.RejectTechnicalVerification(userID, req.RejectionReason); err != nil {
		global.GVA_LOG.Error("技术审核不通过失败", zap.Error(err))
		response.FailWithMessage("技术审核不通过失败", c)
		return
	}
	response.OkWithMessage("技术审核不通过", c)
}

// GetPendingTechnicalVerifications 获取所有未审核的技术审核记录
func (api *TechnicalVerificationApi) GetPendingTechnicalVerifications(c *gin.Context) {
	pendingVerifications, err := auditTechnicalService.GetPendingTechnicalVerifications()
	if err != nil {
		global.GVA_LOG.Error("获取未审核技术审核记录失败!", zap.Error(err))
		response.FailWithMessage("获取未审核技术审核记录失败", c)
		return
	}
	response.OkWithDetailed(pendingVerifications, "获取未审核技术审核记录成功", c)
}

// GetApprovedTechnicalVerifications 获取所有已审核的技术审核记录
func (api *TechnicalVerificationApi) GetApprovedTechnicalVerifications(c *gin.Context) {
	approvedVerifications, err := auditTechnicalService.GetApprovedTechnicalVerifications()
	if err != nil {
		global.GVA_LOG.Error("获取已审核技术审核记录失败!", zap.Error(err))
		response.FailWithMessage("获取已审核技术审核记录失败", c)
		return
	}
	response.OkWithDetailed(approvedVerifications, "获取已审核技术审核记录成功", c)
}
